/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 battlefield_cell.h

	$Header: /heroes4/battlefield_cell.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( BATTLEFIELD_CELL_H_INCLUDED )
#define BATTLEFIELD_CELL_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_combat_object.h"
#include "combat_creature_list.h"
#include "combat_creature_ptr.h"

// -----------------------------------------------------------------------
// t_battlefield_cell class
// -----------------------------------------------------------------------
class t_attackable_object;
enum  t_obstacle_type;
class t_stationary_combat_object;
enum  t_terrain_type;

class t_battlefield_cell
{
public:
	typedef t_combat_creature_list t_creature_list;

	// Constructor
	t_battlefield_cell();

	// Member functions
	void						add( t_abstract_combat_object* object );
	void						add_threat( t_combat_creature* actor );
	t_abstract_combat_object*   get_attackable_object() const;
	t_combat_creature*			get_creature() const;
	t_combat_object_list const& get_objects() const;
	t_stationary_combat_object* get_obstacle() const;
	t_stationary_combat_object* get_obstacle( t_obstacle_type type ) const;
	static t_uint16				get_save_version();
	int							get_terrain_subtype() const;
	t_terrain_type				get_terrain_type() const;
	t_creature_list const&		get_threat_list() const;
	bool						has_brush() const;
	bool						has_gate() const;
	bool						is_blocked( t_combat_object_base const* arg ) const;
	bool						is_blocked( t_combat_object_base const* arg,
											t_combat_object_base const* object_2 ) const;
	bool						is_forbidden() const;
	bool						is_forbidden_by_preset() const;
	bool						is_obscured() const;
	bool						is_obstacle_allowed() const;
	bool						is_quicksand() const;
	bool						read( std::streambuf& stream, t_uint16 version );
	void						remove( t_abstract_combat_object* object );
	void						remove_threat( t_combat_creature* actor );
	void					    set_forbidden( bool arg );
	void						set_forbidden_by_preset( bool arg );
	void						set_gate( bool arg );
	void						set_obstacle_allowed( bool arg );
	void					    set_quicksand( bool arg );
	void						set_terrain_type( t_terrain_type	new_terrain_type,
											      int				new_terrain_subtype );
	bool						write( std::streambuf& stream ) const;
private:
	void						update_obstacles();

	// Data members
	unsigned char			m_terrain_type			: 5;
	unsigned char			m_terrain_subtype		: 3;
	unsigned char			m_has_brush				: 1;
	unsigned char			m_is_quicksand			: 1;
	unsigned char			m_forbidden				: 1;
	unsigned char			m_forbidden_by_preset	: 1;
	unsigned char			m_obstacle_allowed		: 1;
	unsigned char			m_is_obscured			: 1;
	unsigned char			m_has_gate				: 1;
	t_combat_object_list	m_objects;
	t_creature_list			m_threats;
};

inline int t_battlefield_cell::get_terrain_subtype() const
{
	return m_terrain_subtype;
}

inline t_terrain_type t_battlefield_cell::get_terrain_type() const
{
	return t_terrain_type( m_terrain_type );
}

inline t_combat_object_list const& t_battlefield_cell::get_objects() const
{
	return m_objects;
}

inline t_combat_creature_list const& t_battlefield_cell::get_threat_list() const
{
	return m_threats;
}

inline bool t_battlefield_cell::has_brush() const
{
	return m_has_brush != 0;
}

inline bool t_battlefield_cell::has_gate() const
{
	return m_has_gate != 0;
}

inline bool t_battlefield_cell::is_quicksand() const
{
	return m_is_quicksand != 0;
}

inline bool t_battlefield_cell::is_forbidden() const
{
	return m_forbidden != 0;
}

inline bool t_battlefield_cell::is_forbidden_by_preset() const
{
	return m_forbidden_by_preset != 0;
}

inline bool t_battlefield_cell::is_obscured() const
{
	return m_is_obscured != 0;
}

inline bool t_battlefield_cell::is_obstacle_allowed() const
{
	return m_obstacle_allowed != 0;
}

inline void t_battlefield_cell::set_forbidden( bool arg )
{
	m_forbidden = arg;
}

inline void t_battlefield_cell::set_forbidden_by_preset( bool arg )
{
	m_forbidden_by_preset = arg;
}

inline void t_battlefield_cell::set_gate( bool arg )
{
	m_has_gate = arg;
}

inline void t_battlefield_cell::set_obstacle_allowed( bool arg )
{
	m_obstacle_allowed = arg;
}

inline void t_battlefield_cell::set_quicksand( bool arg )
{
	m_is_quicksand = arg;
}

// -----------------------------------------------------------------------
// t_battlefield_cell_vertex class
// -----------------------------------------------------------------------

class t_battlefield_cell_vertex
{
public:
	// Constructor
	t_battlefield_cell_vertex();

	// Member functions
	int		get_height() const;
	void	set_height( int new_height );

private:
	// Data members
	unsigned char	m_height;
};

inline int t_battlefield_cell_vertex::get_height() const
{
	return m_height;
}


#endif // BATTLEFIELD_CELL_H_INCLUDED